import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Set the figure's DPI for better resolution
#plt.rcParams['figure.dpi'] = 300

# Define the grid on the complex plane
x = np.linspace(-2, 2, 100)
y = np.linspace(-2 * np.pi, 2 * np.pi, 100)
X, Y = np.meshgrid(x, y)
Z = X + 0.1j * Y

# Calculate the values of the complex exponential function
W = np.exp(Z)

# Extract the real part, imaginary part, magnitude, and phase
real_part = np.real(W)
imag_part = np.imag(W)
magnitude = np.abs(W)
phase = np.angle(W)

# Create a 2x2 subplot figure
fig = plt.figure(figsize=(12, 10))

# Plot the real part in the top-left subplot
ax1 = fig.add_subplot(221, projection='3d')
ax1.plot_surface(X, Y, real_part, cmap='viridis')
ax1.set_xlabel('Re(z)')
ax1.set_ylabel('Im(z)')
ax1.set_zlabel('Re(e^z)')
ax1.set_title('Real part of e^z')

# Plot the imaginary part in the top-right subplot
ax2 = fig.add_subplot(222, projection='3d')
ax2.plot_surface(X, Y, imag_part, cmap='viridis')
ax2.set_xlabel('Re(z)')
ax2.set_ylabel('Im(z)')
ax2.set_zlabel('Im(e^z)')
ax2.set_title('Imaginary part of e^z')

# Plot the magnitude in the bottom-left subplot
ax3 = fig.add_subplot(223, projection='3d')
ax3.plot_surface(X, Y, magnitude, cmap='viridis')
ax3.set_xlabel('Re(z)')
ax3.set_ylabel('Im(z)')
ax3.set_zlabel('|e^z|')
ax3.set_title('Magnitude of e^z')

# Plot the phase in the bottom-right subplot
ax4 = fig.add_subplot(224, projection='3d')
ax4.plot_surface(X, Y, phase, cmap='viridis')
ax4.set_xlabel('Re(z)')
ax4.set_ylabel('Im(z)')
ax4.set_zlabel('Arg(e^z)')
ax4.set_title('Phase of e^z')

# Adjust the layout to avoid overlapping
plt.tight_layout()

# Display the figure
plt.show()